package com.wwj.depository.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wwj.depository.constant.ConstantFinal;
import com.wwj.depository.dao.DepositoryLocationDao;
import com.wwj.depository.dao.ExpressDao;
import com.wwj.depository.entity.DepositoryExpressInformationEntity;
import com.wwj.depository.entity.DepositoryLocationEntity;
import com.wwj.depository.exception.OpenFeignException;
import com.wwj.depository.feign.FeedbackFeignService;
import com.wwj.depository.feign.ToExpressFeignService;
import com.wwj.depository.service.ExpressService;
import com.wwj.depository.to.AnnouncementTo;
import com.wwj.depository.vo.DataStatisticsVo;
import com.wwj.depository.vo.ExpressVo;
import com.wwj.depository.vo.LineChartVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class ExpressServiceImpl extends ServiceImpl<ExpressDao, DepositoryExpressInformationEntity> implements ExpressService {

    @Resource
    private ExpressDao expressDao;

    @Resource
    private ToExpressFeignService toExpressFeignService;

    @Resource
    private FeedbackFeignService feedbackFeignService;

    @Resource
    private DepositoryLocationDao depositoryLocationDao;

    /**
     * 查询数据库可视化界面所有数据
     * todo 可以使用多线程优化
     */
    @Override
    @Transactional
    public DataStatisticsVo selectManyData() {
        // 创建返回实体类
        DataStatisticsVo dataStatisticsVo = new DataStatisticsVo();
        // 计算当天的起始和结束时间
        String beginDate = DateUtil.beginOfDay(DateUtil.date()).toString();
        String endDate = DateUtil.endOfDay(DateUtil.date()).toString();
        log.info("当前时间范围："+ beginDate + "---" + endDate);
        // 查询数据库
        QueryWrapper<DepositoryExpressInformationEntity> queryWrapper = new QueryWrapper<>();
        // 构建条件
        queryWrapper.ge(ConstantFinal.FIELD_INFORMATION_CREATE_TIME, beginDate).le(ConstantFinal.FIELD_INFORMATION_CREATE_TIME, endDate);
        // 当天快递入库数
        Integer dayWarehouseCount = expressDao.selectCount(queryWrapper);
        // 查询快递寄件数(OpenFeign)
        int daySendNumber = -1;
        try {
            daySendNumber = toExpressFeignService.getDaySendNumber().getData();
        } catch (OpenFeignException e) {
            e.printStackTrace();
        }
        // 公告
        List<AnnouncementTo> announcementTop3 = null;
        try {
            announcementTop3 = feedbackFeignService.getAnnouncementTop3();
        } catch (OpenFeignException e) {
            e.printStackTrace();
        }
        // 当前未处理问题数量
        int noHandleQuestionNumber = -1;
        try {
            noHandleQuestionNumber = feedbackFeignService.getNoHandleQuestion();
        } catch (OpenFeignException e) {
            e.printStackTrace();
        }
        // 获取仓库余量
        QueryWrapper<DepositoryLocationEntity> queryWrapperForLocation = new QueryWrapper<>();
        queryWrapperForLocation.eq(ConstantFinal.FIELD_LOCATION_STORAGE, ConstantFinal.VALUE_LOCATION_NO_STORAGE);
        Integer locationCount = depositoryLocationDao.selectCount(queryWrapperForLocation);
        Integer allLocationCount = depositoryLocationDao.selectCount(new QueryWrapper<>());
        // 计算百分比
        int percentageForLocation = (int) (((1.0 * locationCount) / (1.0 * allLocationCount)) * 100);
        // 计算未取件数
        int noSignNumber = allLocationCount - locationCount;
        // 七天的快递入库数据
        Date date = new Date();
        List<LineChartVo> list = new ArrayList<>();
        for (int i = 0; i >= -6; i--) {
            DateTime dateTime = DateUtil.offsetDay(date, i);  // 获得前一天
            String beginDateForWeek = DateUtil.beginOfDay(dateTime).toString();// 获取每天的范围
            String endDateForWeek = DateUtil.endOfDay(dateTime).toString();
            QueryWrapper<DepositoryExpressInformationEntity> queryWrapperForWeek = new QueryWrapper<>();
            queryWrapperForWeek.ge(ConstantFinal.FIELD_INFORMATION_CREATE_TIME, beginDateForWeek).le(ConstantFinal.FIELD_INFORMATION_CREATE_TIME, endDateForWeek);
            Integer count = expressDao.selectCount(queryWrapperForWeek);
            // 存储到集合中
            list.add(new LineChartVo(dateTime.toString("MM-dd"), count));
        }
        Collections.reverse(list);  // 反转数据
        log.info("============================================");
        // 日志
        log.info("当天快递入库数:" + dayWarehouseCount);
        log.info("快递寄件数：" + daySendNumber);
        log.info("当前未取件数：" + noSignNumber);
        log.info("前三条公告：" + announcementTop3);
        log.info("当前未处理问题数量：" + noHandleQuestionNumber);
        log.info("剩余库存数量：" + locationCount);
        log.info("所有库存数量：" + allLocationCount);
        log.info("仓库余量百分比：" + percentageForLocation);
        log.info("============================================");
        // 封装实体类
        dataStatisticsVo.setDayWarehouseCount(dayWarehouseCount);
        dataStatisticsVo.setDaySendNumber(daySendNumber);
        dataStatisticsVo.setNoSignNumber(noSignNumber);
        dataStatisticsVo.setAnnouncementTop3(announcementTop3);
        dataStatisticsVo.setNoHandleQuestion(noHandleQuestionNumber);
        dataStatisticsVo.setPercentageForLocation(percentageForLocation);
        // 封装七天结果
        dataStatisticsVo.setListForWeek(list);
        return dataStatisticsVo;
    }

    @Override
    public PageInfo<ExpressVo> selectExpressData(String currentPage, String pageSize, String query) {
        // 设置分页
        Page<ExpressVo> page = PageHelper.startPage(Integer.parseInt(currentPage), Integer.parseInt(pageSize));
        // 如果没有query
        if (query.isEmpty()) {
            // 连表查询
            expressDao.selectExpressLocationList();
        }else{
            // 有query
            expressDao.selectExpressLocationListWithQuery(query);
        }
        return page.toPageInfo();
    }
}
